import { ModalForm, ProFormSelect } from '@/components/Pro/';
import { SearchOutlined } from '@ant-design/icons';
import { useRequest, useSize } from 'ahooks';
import { Flex, Input, message, Spin, Tree, TreeProps, Typography } from 'antd';
import React, { useEffect, useState } from 'react';
import { Link, useIntl, useLocation } from 'umi';

import HandleBtn from '@/components/HandleBar/btn';

import Tabs, { TabsProps } from '@/components/Tabs';
import {
  deviceTreeControllerDeviceTree,
  deviceTreeControllerOfflineStatistics,
} from '@/services/ess/deviceTree';
import { BasicInfo } from './BasicInfo';
import { DailyCurve } from './DailyCurve';
import './index.less';
import { RealtimeInfo } from './RealtimeInfo';
import { SelectedDeviceNodeContext } from './SelectedDeviceNodeContext';
import { DeviceTreeDataNode } from './types';

const { Text } = Typography;

function transformDataToTreeFormat(
  data: API.DeviceTreeVO[],
  prefix = 'node_',
): DeviceTreeDataNode[] {
  return data.map((item, index) => {
    const key = `${prefix}${index}`;
    return {
      title: item.deviceName,
      key: key,
      ...item,
      children: item.subDevices ? transformDataToTreeFormat(item.subDevices, `${key}_`) : [],
    };
  });
}

function hasAreaOrOther(data: API.DeviceTreeVO[], type: string): boolean {
  let hasBol = false;

  for (const node of data) {
    if (node?.nodeType === type) {
      hasBol = true;
      break;
    }
    if (node?.children && node?.children.length) {
      hasBol = hasAreaOrOther(node?.children, type);
      if (hasBol) {
        break;
      }
    }
  }

  return hasBol;
}

const findNodePath = (
  key: React.Key,
  data: DeviceTreeDataNode[],
  path: string[] = [],
): string[] => {
  for (const node of data) {
    if (node.key === key) {
      return [...path, node.deviceName!];
    }
    if (node.children) {
      const childPath = findNodePath(key, node.children, [...path, node.deviceName!]);
      if (childPath.length) {
        return childPath;
      }
    }
  }
  return [];
};

const INCLUDE_TYPES = ['ROOT', 'STATION', 'AREA', 'BOX', 'CABINET', 'PCS', 'METER', 'LC'];

const shouldIncludeType = (deviceType: string, nodeType: string) => {
  if (!INCLUDE_TYPES.includes(deviceType)) {
    return false;
  }

  // 排除 PCS 和 METER，当它们的 nodeType 为 DEVICE_GROUP 时
  if (
    (deviceType === 'PCS' || deviceType === 'METER' || deviceType === '') &&
    nodeType === 'DEVICE_GROUP'
  ) {
    return false;
  }

  return true;
};

const StationRealtimeMonitor: React.FC = () => {
  const [seconds, setSecond] = useState<number>(() => {
    // 从 localStorage 读取值，若没有则默认为 60
    const storedSeconds = localStorage.getItem('refreshCycle');
    return storedSeconds ? Number(storedSeconds) : 60;
  });
  const [createModalOpen, handleModalOpen] = useState<boolean>(false);
  const { data, loading } = useRequest(() =>
    deviceTreeControllerDeviceTree({
      needDeviceCount: 'true',
      needGroupNode: 'true',
      needEmmuNode: 'true',
    }),
  );
  const [treeData, setTreeData] = useState<DeviceTreeDataNode[]>([]);

  const treeContainerRef = React.useRef<HTMLDivElement>(null);
  const size = useSize(treeContainerRef);

  const [activeTabKey, setActiveTabKey] = useState('1');
  const [selectedDevice, setSelectedDevice] = useState<DeviceTreeDataNode & { path: string[] }>();
  const selectedDeviceType = selectedDevice?.deviceType ?? selectedDevice?.nodeType ?? '';

  const [expandedKeys, setExpandedKeys] = useState<React.Key[]>([]);
  const [autoExpandParent, setAutoExpandParent] = useState<boolean>(true);
  const [hasArea, sethasArea] = useState<boolean>(false);
  const intl = useIntl();
  const location = useLocation();

  const [deviceInfo, setDeviceInfo] = useState<{
    ts?: string | undefined;
    onLine?: string | undefined;
  }>({
    ts: undefined,
    onLine: undefined,
  });

  const [isRefesh, setIsRefesh] = useState<boolean>(false); //用来定义下面的组件是否进行相应的刷新
  const [searchValue, setSearchValue] = useState<string>('');
  const [searchExpandedKeys, setSearchExpandedKeys] = useState<React.Key[]>([]);
  const [filteredTreeData, setFilteredTreeData] = useState<DeviceTreeDataNode[]>([]);
  const [soc, setSoc] = useState<number | undefined>(undefined);

  // 新增：根据 key 查找节点的函数
  const findNodeByKey = (
    key: string,
    nodes: DeviceTreeDataNode[],
    targetKey: string = 'key',
  ): DeviceTreeDataNode | null => {
    for (const node of nodes) {
      if (node[targetKey] === key) {
        return node;
      }
      if (node.children) {
        const found = findNodeByKey(key, node.children, targetKey);
        if (found) {
          return found;
        }
      }
    }
    return null;
  };

  // 新增：获取所有父节点的 key
  const getParentKeys = (
    key: React.Key,
    nodes: DeviceTreeDataNode[],
    parentKeys: React.Key[] = [],
  ): React.Key[] => {
    for (const node of nodes) {
      if (node.key === key) {
        return parentKeys;
      }
      if (node.children) {
        const found = getParentKeys(key, node.children, [...parentKeys, node.key]);
        if (found.length) {
          return found;
        }
      }
    }
    return [];
  };

  const filterTreeData = (
    nodes: DeviceTreeDataNode[],
    searchText: string,
  ): DeviceTreeDataNode[] => {
    return nodes
      .map((node) => {
        const matchNode = node.deviceName?.toLowerCase().includes(searchText.toLowerCase());
        const filteredChildren = node.children ? filterTreeData(node.children, searchText) : [];

        if (matchNode || filteredChildren.length > 0) {
          return {
            ...node,
            children: filteredChildren,
          };
        }
        return null;
      })
      .filter((node): node is DeviceTreeDataNode => node !== null);
  };

  const getExpandedKeys = (
    nodes: DeviceTreeDataNode[],
    searchText: string,
    parentKey?: React.Key,
  ): React.Key[] => {
    let expandedKeys: React.Key[] = [];

    nodes.forEach((node) => {
      if (node.deviceName?.toLowerCase().includes(searchText.toLowerCase())) {
        if (parentKey) expandedKeys.push(parentKey);
      }
      if (node.children) {
        expandedKeys = [...expandedKeys, ...getExpandedKeys(node.children, searchText, node.key)];
      }
    });

    return expandedKeys;
  };

  const onSearch = (value: string) => {
    setSearchValue(value);
    if (!value.trim()) {
      setFilteredTreeData(treeData || []);
      setSearchExpandedKeys([]);
      return;
    }

    const filtered = filterTreeData(treeData || [], value);
    setFilteredTreeData(filtered);

    const newExpandedKeys = getExpandedKeys(treeData || [], value);
    setSearchExpandedKeys([...new Set(newExpandedKeys)]);
    setAutoExpandParent(true);
  };

  // 新增：查找箱节点的函数
  const findBoxNode = (nodes: DeviceTreeDataNode[]): DeviceTreeDataNode | null => {
    for (const node of nodes) {
      if (
        (node.deviceType === 'BOX' || node.deviceType === 'CABINET') &&
        node.nodeType === 'DEVICE_GROUP'
      ) {
        return node;
      }
      if (node.children) {
        const found = findBoxNode(node.children);
        if (found) {
          return found;
        }
      }
    }
    return null;
  };

  useEffect(() => {
    if (data && data.data) {
      const transformedData = transformDataToTreeFormat([data.data]);
      setTreeData(transformedData);
      sethasArea(hasAreaOrOther(transformedData, 'AREA'));
      // 从 URL 中获取 key 参数
      const params = new URLSearchParams(location.search);
      const keyFromUrl = params.get('key');
      const batteryParam = params.get('battery');

      if (batteryParam === 'true') {
        // 如果 URL 中有 battery=true，查找并展开箱节点
        const boxNode = findBoxNode(transformedData);
        if (boxNode) {
          const path = findNodePath(boxNode.key, transformedData);
          setSelectedDevice({ path, ...boxNode });
          const parentKeys = getParentKeys(boxNode.key, transformedData);
          setExpandedKeys([...parentKeys, boxNode.key]);
          return;
        }
      }

      if (keyFromUrl) {
        // 如果 URL 中有 key，找到对应的节点
        const node = findNodeByKey(keyFromUrl, transformedData);
        if (node) {
          const path = findNodePath(node.key, transformedData);
          setSelectedDevice({ path, ...node });

          // 展开到该节点的所有父节点
          const parentKeys = getParentKeys(node.key, transformedData);
          setExpandedKeys([...parentKeys, node.key]);
        }
      } else {
        // 如果 URL 中没有 key，使用默认行为
        const defaultExpandedKey = transformedData[0].key;
        setExpandedKeys([defaultExpandedKey]);
        const path = findNodePath(defaultExpandedKey, transformedData);
        setSelectedDevice({ path, ...transformedData[0] });
      }
    }
  }, [data]);

  const changeTitle = () => {
    switch (selectedDevice?.deviceType) {
      case 'STATION':
        return `${intl.formatMessage({
          id: 'stationRealtimeMonitoring.realTimeInformationOfPlant',
        })}`;
      case 'AREA':
        return `${selectedDevice?.deviceName}${intl.formatMessage({
          id: 'stationRealtimeMonitoring.realTimeInfo',
        })}`;
      default:
        if (selectedDevice?.path && selectedDevice.path.length >= 2) {
          return `${selectedDevice?.path.slice(1).join('_')}`; //做相应层级的名字的连接
        }
    }
  };

  const showTab = shouldIncludeType(selectedDeviceType, selectedDevice?.nodeType || '');
  const tabItems: NonNullable<TabsProps['items']> = [
    {
      label: changeTitle(),
      key: '1',
    },
  ];

  const onExpand: TreeProps['onExpand'] = (expandedKeysValue) => {
    setExpandedKeys(expandedKeysValue);
    setAutoExpandParent(false);
  };

  const filterNode = (node: DeviceTreeDataNode) => {
    const { deviceType, nodeType } = node;

    // 第一个条件：activeTabKey 是 '3' 并且 deviceType 是特定值之一
    const condition1 =
      activeTabKey === '3' &&
      typeof deviceType === 'string' &&
      ['STACK', 'CLUSTER', 'BMS', 'EMMU', 'BMU'].includes(deviceType);

    // 新增条件：deviceType 是 PCS、METER、CABINET 并且 nodeType 是 DEVICE_GROUP
    const condition2 =
      activeTabKey === '3' &&
      typeof deviceType === 'string' &&
      ['PCS', 'METER', 'CABINET', 'CHARGE_PILE', 'INVERTER', 'TRANSFORMER'].includes(deviceType) &&
      nodeType === 'DEVICE_GROUP';

    if (condition1 || condition2) {
      message.warning(
        intl.formatMessage({
          id: 'stationRealtimeMonitoring.baseInfoTips',
        }),
      );
      return false; // 阻止节点被选中
    }
    return true;
  };

  const updateTreeDataWithOfflineCount = (
    nodes: DeviceTreeDataNode[],
    key: React.Key,
    offlineCount: number,
  ): DeviceTreeDataNode[] => {
    return nodes.map((node) => {
      if (node.key === key) {
        return { ...node, offlineCount };
      }
      if (node.children) {
        return {
          ...node,
          children: updateTreeDataWithOfflineCount(node.children, key, offlineCount),
        };
      }
      return node;
    });
  };

  const onSelect: TreeProps<DeviceTreeDataNode>['onSelect'] = async (
    selectedKeys: React.Key[],
    info,
  ) => {
    // console.log('selectedKeys: ', selectedKeys, 'info: ', info);
    if (info.node && treeData) {
      if (!filterNode(info.node)) {
        return;
      }
      const path = findNodePath(info.node.key, treeData);
      console.log('我点击以后', { path, ...info.node });
      setSelectedDevice({ path, ...info.node });
      const newSelectedDevice = { path, ...info.node };
      setSelectedDevice(newSelectedDevice);

      try {
        const response = await deviceTreeControllerOfflineStatistics({
          deviceType: newSelectedDevice.deviceType,
          deviceCode: newSelectedDevice.deviceCode,
          nodeType: newSelectedDevice.nodeType,
        });
        if (response.success && response.data !== undefined) {
          // Update the tree data with the new offline count
          const updatedTreeData = updateTreeDataWithOfflineCount(
            treeData,
            info.node.key,
            response.data,
          );
          setTreeData(updatedTreeData);
        }
      } catch (error) {
        console.error('Error fetching offline statistics:', error);
      }
    }
  };

  const onChangeTab = (key: string) => setActiveTabKey(key);

  const handleBasicInfoClick = () => {
    if (!selectedDevice) {
      return;
    }

    const { deviceType, nodeType } = selectedDevice;

    // 检查是否应该阻止切换
    const shouldPreventSwitch =
      (typeof deviceType === 'string' &&
        ['STACK', 'CLUSTER', 'BMS', 'EMMU', 'BMU'].includes(deviceType)) ||
      (typeof deviceType === 'string' &&
        ['PCS', 'METER', 'CABINET', 'CHARGE_PILE', 'INVERTER', 'TRANSFORMER'].includes(
          deviceType,
        ) &&
        nodeType === 'DEVICE_GROUP');

    if (shouldPreventSwitch) {
      // 显示警告消息
      message.warning(
        intl.formatMessage({
          id: 'stationRealtimeMonitoring.baseInfoTips',
        }),
      );
    } else {
      // 只有在不应该阻止切换时才设置 activeTabKey
      setActiveTabKey('3');
    }
  };

  const titleRender = (node: DeviceTreeDataNode) => {
    return (
      <>
        <p style={{ margin: 0 }}>{node.deviceName}</p>
        {((node.faultCount ?? 0) > 0 || (node.offlineCount ?? 0) > 0 || (node.soc ?? 0) > 0) && (
          <div
            style={{
              display: 'flex',
              gap: 4,
              alignItems: 'center',
              flexWrap: 'wrap',
            }}
          >
            {node.soc !== null && <p className="htn-badge htn-badge-soc">{`${node.soc}%`}</p>}
            {/* {(node.faultCount ?? 0) > 0 && (
              <span style={{ marginLeft: 8 }} className="htn-badge htn-badge-fault">
                {`${intl.formatMessage({ id: 'baseInfo.fault' })}: ${node.faultCount ?? 0}/${
                  node.totalCount ?? 0
                }`}
              </span>
            )} */}
            {(node.offlineCount ?? 0) > 0 && (
              <span style={{ marginLeft: 8 }} className="htn-badge htn-badge-offline">
                {`${intl.formatMessage({ id: 'baseInfo.offlineNumber' })}: ${
                  node.offlineCount ?? 0
                }`}
              </span>
            )}
          </div>
        )}
      </>
    );
  };

  const handleFormFinish = async (values: any) => {
    console.log(values);
    setSecond(values.seconds);
    localStorage.setItem('refreshCycle', values.seconds); // 存储到 localStorage
    handleModalOpen(false);
  };

  // 这里设置定时器
  useEffect(() => {
    const interval = setInterval(() => {
      setIsRefesh(true);
    }, seconds * 1000);

    // 清理定时器
    return () => clearInterval(interval);
  }, [seconds]);

  return (
    <SelectedDeviceNodeContext.Provider
      value={{
        selectedDevice,
        determinationParameter: { hasArea: hasArea, treeData: treeData },
        getData: async () => [],
        deviceInfo,
        setDeviceInfo,
        isRefesh,
        setIsRefesh,
        setSelectedDevice,
        soc,
        setSoc,
        updateNodeSOC: (nodeKey: string, newSOC: number) => {
          setTreeData((prevTreeData) => {
            const updateNode = (nodes: DeviceTreeDataNode[]): DeviceTreeDataNode[] => {
              return nodes.map((node) => {
                if (node.key === nodeKey) {
                  if (node.offlineCount === 0) {
                    return { ...node, soc: newSOC };
                  }
                }
                if (node.children) {
                  return { ...node, children: updateNode(node.children) };
                }
                return node;
              });
            };
            return updateNode(prevTreeData);
          });
        },
        updateNOdeSelect: (deviceCode: string) => {
          const node = findNodeByKey(deviceCode, treeData, 'deviceCode');
          if (node) {
            const path = findNodePath(node.key, treeData);
            setSelectedDevice({ path, ...node });

            // 展开到该节点的所有父节点
            const parentKeys = getParentKeys(node.key, treeData);
            setExpandedKeys([...parentKeys, node.key]);
          }
        },
      }}
    >
      <Spin spinning={loading} wrapperClassName="station-realtime-monitoring-spin">
        <Flex style={{ height: '100%', backgroundColor: '#fff' }}>
          <Flex
            vertical
            style={{
              width: '300px',
              padding: 20,
              flex: '0 0 300px',
              borderRight: '1px solid #D1D5E0',
            }}
            gap={10}
          >
            <Input
              placeholder={intl.formatMessage({ id: 'siteManage.enterPlease' })}
              addonAfter={<SearchOutlined />}
              onChange={(e) => onSearch(e.target.value)}
            />
            <div ref={treeContainerRef} style={{ flex: 1, overflowX: 'auto' }}>
              <Tree
                height={size?.height || 0}
                defaultExpandAll={true}
                treeData={searchValue ? filteredTreeData : treeData}
                expandedKeys={searchValue ? searchExpandedKeys : expandedKeys}
                selectedKeys={selectedDevice && [selectedDevice.key]}
                autoExpandParent={autoExpandParent}
                titleRender={titleRender}
                onSelect={onSelect}
                onExpand={onExpand}
              />
            </div>
          </Flex>
          <Flex vertical style={{ flex: 1 }}>
            <header
              style={{
                display: 'flex',
                alignItems: 'center',
                borderBottom: '1px solid #D1D5E0',
              }}
            >
              <Tabs
                style={{ padding: 0, cursor: 'none !important' }}
                items={tabItems}
                activeKey={activeTabKey}
                onChange={onChangeTab}
              />
              <div
                style={{
                  cursor: 'pointer',
                  fontSize: '12px',
                  fontWeight: 'normal',
                  paddingLeft: '-12px',
                  cursor: 'none',
                }}
              >
                {deviceInfo?.onLine ? (
                  <span
                    style={{
                      marginRight: '12px',
                      color: deviceInfo?.onLine === '1' ? 'green' : 'red',
                    }}
                  >
                    {deviceInfo?.onLine === '1'
                      ? `${intl.formatMessage({ id: 'bigdata.online' })}`
                      : `${intl.formatMessage({ id: 'bigdata.offline' })}`}
                  </span>
                ) : null}

                {deviceInfo?.ts ? (
                  <span>
                    {intl.formatMessage({ id: 'stationRealtimeMonitoring.collectionTime' })}
                    {deviceInfo?.ts}
                  </span>
                ) : null}
              </div>

              <div style={{ marginLeft: 'auto', display: 'flex', alignItems: 'center' }}>
                <Flex
                  style={{
                    fontSize: 16,
                    whiteSpace: 'nowrap',
                  }}
                >
                  <div style={{ display: 'flex', gap: '30px', alignItems: 'center' }}>
                    <Text
                      style={{
                        cursor: 'pointer',
                        fontSize: '16px',
                        color: activeTabKey === '2' ? '#222' : '#666',
                        fontWeight: activeTabKey === '2' ? 'bold' : 'normal',
                      }}
                      onClick={() => setActiveTabKey('2')}
                    >
                      {intl.formatMessage({ id: 'stationRealtimeMonitoring.dayCurve' })}
                    </Text>
                    {showTab && (
                      <>
                        <Text
                          style={{
                            cursor: 'pointer',
                            fontSize: '16px',
                            color: activeTabKey === '3' ? '#222' : '#666',
                            fontWeight: activeTabKey === '3' ? 'bold' : 'normal',
                          }}
                          onClick={handleBasicInfoClick}
                        >
                          {intl.formatMessage({ id: 'stationRealtimeMonitoring.basicInformation' })}
                        </Text>
                      </>
                    )}
                    <Link to={'/stationmonitor/hisCurve'}>
                      {intl.formatMessage({ id: 'stationRealtimeMonitoring.historicalCurve' })}
                    </Link>
                    <Link to={`/stationmonitor/history?key=${selectedDevice?.key}`}>
                      {intl.formatMessage({ id: 'stationRealtimeMonitoring.historicalData' })}
                    </Link>
                  </div>
                  {/* <div style={{position:'absolute',right:'20px'}}>
                    我这里测试文仔
                  </div> */}
                </Flex>
                <HandleBtn
                  style={{ paddingRight: '10px' }}
                  handleType="parameter"
                  onClick={() => {
                    handleModalOpen(true);
                  }}
                ></HandleBtn>
              </div>
            </header>

            {/* tabs content */}
            <main style={{ flexGrow: 1, position: 'relative', overflow: 'auto' }}>
              <div
                style={{
                  position: 'absolute',
                  left: 0,
                  top: 0,
                  right: 0,
                  minHeight: '100%',
                }}
              >
                {activeTabKey === '1' && <RealtimeInfo />}
                {activeTabKey === '2' && <DailyCurve currentTreeNode={selectedDevice} />}
                {activeTabKey === '3' && <BasicInfo />}
              </div>
            </main>
          </Flex>
        </Flex>
        <ModalForm
          open={createModalOpen}
          modalProps={{
            destroyOnClose: true,
            onCancel: () => {
              handleModalOpen(false);
            }, // 点击取消按钮或者关闭按钮时调用
          }}
          initialValues={{ seconds: String(seconds) }}
          width={835}
          colProps={{ md: 12 }}
          onFinish={handleFormFinish}
          onCancel={() => {
            handleModalOpen(false);
          }}
        >
          <ProFormSelect
            name="seconds"
            label={intl.formatMessage({
              id: 'remoteUpgradeMangment.mainWiringDiagram.refreshCycle',
            })}
            valueEnum={{
              30: '30s',
              60: '60s',
              90: '90s',
              120: '120s',
              300: `5${intl.formatMessage({
                id: 'remoteUpgradeMangment.versionManagement.minutesFull',
              })}`,
              600: `10${intl.formatMessage({
                id: 'remoteUpgradeMangment.versionManagement.minutesFull',
              })}`,
              1200: `20${intl.formatMessage({
                id: 'remoteUpgradeMangment.versionManagement.minutesFull',
              })}`,
              1800: `30${intl.formatMessage({
                id: 'remoteUpgradeMangment.versionManagement.minutesFull',
              })}`,
            }}
            rules={[
              {
                required: true,
                message: '刷新周期为必填项目',
              },
            ]}
          />
        </ModalForm>
      </Spin>
    </SelectedDeviceNodeContext.Provider>
  );
};

export default StationRealtimeMonitor;
